/******************************************************************************
* 文件名称: u_syscall.h
* 内容摘要: 系统调用接口头文件
* 创建者の: 孔佳伟
* 个人主页: https://gitee.com/thin-wind/jump
* 修改记录: 
******************************************************************************/


#ifndef __U_SYSCALL_H_
#define __U_SYSCALL_H_

#include <common.h>
#include <queue.h>

#define _NR_TaskDestory             0
#define _NR_print                   1
#define _NR_SetCursorPos            2
#define _NR_MutexCreat              3
#define _NR_MutexLock               4
#define _NR_MutexUnLock             5
#define _NR_MutexDestory            6
#define _NR_MutexTryLock            7
#define _NR_EventCreat              8
#define _NR_WaitEvent               9
#define _NR_SetEvent                10
#define _NR_ClearEvent              11
#define _NR_EventDestory            12
#define _NR_ReadKey                 13
#define _NR_GetKernelVersion        14
#define _NR_CreatFileInRoot         15
#define _NR_DeleteFileInRoot        16
#define _NR_RenameFileInRoot        17
#define _NR_FileOpen                18
#define _NR_FileClose               19
#define _NR_FileWrite               20
#define _NR_FileRead                21
#define _NR_GetFileLen              22
#define _NR_FileTell                23
#define _NR_FileSeek                24


// 无参数的系统调用
#define _SYS_CALL0(_NR) ({          \
        U32 retval;                 \
        asm volatile(               \
            "int $0x80"             \
            : "=a" (retval)         \
            : "a" (_NR)             \
            : "memory"              \
            );                      \
        retval;                     \
})

// 一个参数的系统调用
#define _SYS_CALL1(_NR, ARG1)   ({  \
        U32 retval;                 \
        asm volatile(               \
            "int $0x80"             \
            : "=a" (retval)         \
            : "a"(_NR), "b"(ARG1)   \
            : "memory"              \
        );                          \
        retval;                     \
})

// 两个参数的系统调用
#define _SYS_CALL2(_NR, ARG1, ARG2)   ({            \
        U32 retval;                                 \
        asm volatile(                               \
            "int $0x80"                             \
            : "=a" (retval)                         \
            : "a"(_NR), "b"(ARG1), "c"(ARG2)        \
            : "memory"                              \
        );                                          \
        retval;                                     \
})

// 三个参数的系统调用
#define _SYS_CALL3(_NR, ARG1, ARG2, ARG3)   ({          \
        U32 retval;                                     \
        asm volatile(                                   \
            "int $0x80"                                 \
            : "=a" (retval)                             \
            : "a"(_NR), "b"(ARG1), "c"(ARG2), "d"(ARG3) \
            : "memory"                                  \
        );                                              \
        retval;                                         \
})

// 四个参数的系统调用
#define _SYS_CALL4(_NR, ARG1, ARG2, ARG3, ARG4)   ({                    \
        U32 retval;                                                     \
        asm volatile(                                                   \
            "int $0x80"                                                 \
            : "=a" (retval)                                             \
            : "a"(_NR), "b"(ARG1), "c"(ARG2), "d"(ARG3), "S"(ARG4)      \
            : "memory"                                                  \
        );                                                              \
        retval;                                                         \
})

// 五个参数的系统调用
#define _SYS_CALL5(_NR, ARG1, ARG2, ARG3, ARG4, ARG5)   ({                      \
        U32 retval;                                                             \
        asm volatile(                                                           \
            "int $0x80"                                                         \
            : "=a" (retval)                                                     \
            : "a"(_NR), "b"(ARG1), "c"(ARG2), "d"(ARG3), "S"(ARG4), "D"(ARG4)   \
            : "memory"                                                          \
        );                                                                      \
        retval;                                                                 \
})


/******************************************************************************
* 函数名称: void TaskDestory(void)
* 功能说明: 销毁当前任务
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 无
******************************************************************************/
E_RET TaskDestory(void);

/******************************************************************************
* 函数名称: U32 print(const char * fmt, ...)
* 功能说明: 用户打印
* 输入参数: const char * fmt    --输出格式, 目前支持的格式: 
                                        %c: 字符
                                        %s: 字符串 
                                        %x: 十六进制 
                                        %d: 十进制
    　　　　...                 --可变参数  
* 输出参数: 无
* 函数返回: 成功打印的字符个数
* 其它说明: 无
******************************************************************************/
U32 print(const char * fmt, ...);

/******************************************************************************
* 函数名称: E_RET SetCursorPos(U16 x, U16 y)
* 功能说明: 设置光标位置
* 输入参数: U16 x		--横坐标
    　　　　U16 y       --纵坐标
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET SetCursorPos(U16 x, U16 y);


typedef struct MUTEX
{
    LIST_NODE   node;       // 互斥锁链表节点
    U08         lock;       // 锁状态
    QUEUE       wait;       // 等待该互斥锁的任务队列（每个互斥锁都有一个等待队列）
} MUTEX;

/******************************************************************************
* 函数名称: MUTEX* SYS_MutexCreat(void)
* 功能说明: 创建互斥锁
* 输入参数: 无
* 输出参数: 无
* 函数返回: MUTEX*          --互斥锁
* 其它说明: 
******************************************************************************/
MUTEX* MutexCreat(void);

/******************************************************************************
* 函数名称: E_RET SYS_MutexLock(MUTEX* mutex)
* 功能说明: 上锁
* 输入参数: MUTEX* mutex    --互斥锁
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET MutexLock(MUTEX* mutex);

/******************************************************************************
* 函数名称: E_RET MutexTryLock(MUTEX* mutex)
* 功能说明: 尝试上锁
* 输入参数: MUTEX* mutex    --互斥锁
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 任务不会被挂起
******************************************************************************/
E_RET MutexTryLock(MUTEX* mutex);

/******************************************************************************
* 函数名称: E_RET SYS_MutexLock(MUTEX* mutex)
* 功能说明: 解锁
* 输入参数: MUTEX* mutex    --互斥锁
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET MutexUnLock(MUTEX* mutex);

/******************************************************************************
* 函数名称: E_RET SYS_MutexLock(MUTEX* mutex)
* 功能说明: 销毁互斥锁
* 输入参数: MUTEX* mutex    --互斥锁
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET MutexDestory(MUTEX* mutex);


typedef struct EVENT
{
    LIST_NODE   node;       // 事件链表节点
    U08         event;      // 事件状态
    QUEUE       wait;       // 等待该事件的任务队列（每个事件都有一个等待队列）
} EVENT;

/******************************************************************************
* 函数名称: EVENT* EventCreat(void)
* 功能说明: 创建事件
* 输入参数: 无
* 输出参数: 无
* 函数返回: EVENT*          --事件
* 其它说明: 
******************************************************************************/
EVENT* EventCreat(void);

/******************************************************************************
* 函数名称: E_RET WaitEvent(EVENT* event)
* 功能说明: 事件
* 输入参数: EVENT* event    --事件
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET WaitEvent(EVENT* event);

/******************************************************************************
* 函数名称: E_RET SetEvent(EVENT* event)
* 功能说明: 设置事件
* 输入参数: EVENT* event    --事件
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET SetEvent(EVENT* event);

/******************************************************************************
* 函数名称: E_RET ClearEvent(EVENT* event)
* 功能说明: 清除事件
* 输入参数: EVENT* event    --事件
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET ClearEvent(EVENT* event);

/******************************************************************************
* 函数名称: E_RET EventDestory(EVENT* event)
* 功能说明: 销毁事件
* 输入参数: EVENT* event    --事件
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET EventDestory(EVENT* event);

/******************************************************************************
* 函数名称: U32 ReadKey(void)
* 功能说明: 读取按键值
* 输入参数: 无
* 输出参数: 无
* 函数返回: 按键值
* 其它说明: 无
******************************************************************************/
U32 ReadKey(void);

/******************************************************************************
* 函数名称: char* GetKernelVersion(void)
* 功能说明: 获取内核版本信息
* 输入参数: 无
* 输出参数: 无
* 函数返回: 内核版本号字符串首地址
* 其它说明: 无
******************************************************************************/
char* GetKernelVersion(void);

/******************************************************************************
* 函数名称: E_RET CreatFileInRoot(const U08* name)
* 功能说明: 在根目录 root 下创建一个文件
* 输入参数: const U08* name      --要创建的文件名
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET CreatFileInRoot(const U08* name);

/******************************************************************************
* 函数名称: E_RET DeleteFileInRoot(const U08* name)
* 功能说明: 在根目录 root 下删除一个文件
* 输入参数: const U08* name      --要删除的文件名
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET DeleteFileInRoot(const U08* name);

/******************************************************************************
* 函数名称: E_RET RenameFileInRoot(const U08* old, const U08* new)
* 功能说明: 文件重命名
* 输入参数: const U08* old          --旧文件名
    　　　　const U08* new          --新文件名
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET RenameFileInRoot(const U08* old, const U08* new);

/******************************************************************************
* 函数名称: U32 FileOpen(const U08* name)
* 功能说明: 打开文件
* 输入参数: const U08* name          --文件名
* 输出参数: 无
* 函数返回: U32               --文件描述符
* 其它说明: 无
******************************************************************************/
U32 FileOpen(const U08* name);

/******************************************************************************
* 函数名称: E_RET FileClose(U32 fd)
* 功能说明: 关闭文件
* 输入参数: U32 fd       --文件描述符
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET FileClose(U32 fd);

/******************************************************************************
* 函数名称: U32 FileWrite(U32 fd, U08* buf, U32 len)
* 功能说明: 向文件中写入数据
* 输入参数: U32 fd       --文件描述符
    　　　　U08* buf            --写入的数据缓冲区首地址
    　　　　U32 buf             --要写入的数据长度
* 输出参数: 无
* 函数返回: 成功写入文件的数据长度
* 其它说明: 无
******************************************************************************/
U32 FileWrite(U32 fd, U08* buf, U32 len);

/******************************************************************************
* 函数名称: U32 FileRead(U32 fd, U08* buf, U32 len)
* 功能说明: 从文件中读取数据
* 输入参数: U32 fd       --文件描述符
    　　　　U08* buf            --数据读入的缓冲区首地址
    　　　　U32 buf             --要读取的数据长度
* 输出参数: 无
* 函数返回: 成功读取文件的数据长度
* 其它说明: 无
******************************************************************************/
U32 FileRead(U32 fd, U08* buf, U32 len);

/******************************************************************************
* 函数名称: U32 GetFileLen(U32 fd)
* 功能说明: 获取文件数据大小
* 输入参数: U32 fd       --文件描述符
* 输出参数: 无
* 函数返回: 文件数据大小
* 其它说明: 无
******************************************************************************/
U32 GetFileLen(U32 fd);

/******************************************************************************
* 函数名称: U32 FileTell(U32 fd)
* 功能说明: 得到文件当前读写位置指针相对于文件首的偏移字节数
* 输入参数: U32 fd       --文件描述符
* 输出参数: 无
* 函数返回: 文件当前读写位置指针相对于文件首的偏移字节数
* 其它说明: 无
******************************************************************************/
U32 FileTell(U32 fd);

/******************************************************************************
* 函数名称: E_RET FileSeek(U32 fd, U32 pos)
* 功能说明: 设置文件当前读写指针位置
* 输入参数: U32 fd       --文件描述符
    　　　　U32 pos             --读写指针设置位置
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET FileSeek(U32 fd, U32 pos);

#endif
